#include <REGX52.H>
#include <LCD1602.h>
#include "MatrixKey.h"

#define maxLength 8

typedef struct StackInt{
    int StackPoint;
    int Stack[maxLength];
}stackint;

typedef struct StackSign{
    int StackPoint;
    char Stack[maxLength];
}stacksign;

int juadgeNum(char ch)
{
    if (ch>='0' && ch<='9')
    {
        return 1;
    }
    return 0;
}

void Intpush(stackint* stack,int index)
{
    if (stack->StackPoint>=maxLength)
    {
        return;
    }
    stack->Stack[++(stack->StackPoint)]=index;
    
}

int Intpop(stackint* stack)
{
    if (stack->StackPoint!=-1)
    {
        return stack->Stack[stack->StackPoint--];
    }
    return -1;
    
}

void charpush(stacksign* stack,char index)
{
    if (stack->StackPoint>=maxLength)
    {
        return;
    }
    stack->Stack[++(stack->StackPoint)]=index;  
}

char charpop(stacksign* stack)
{
    if (stack->StackPoint!=-1)
    {
        return stack->Stack[stack->StackPoint--];
    }
    return -1;
    
}

void charToNum(stackint* stack,int* intcounts)
{
    int accumulation=0;
    int index=0;
    int count=0;
    while (intcounts[index]!=-1)
    {
        count=count*10+intcounts[index++];
    }
    Intpush(stack,count); 
}

int judgeSigned(char ch1,char ch2)
{   
    if(ch1==ch2)
    {
        return 1;
    }
    if (ch1=='*' && ch2=='/')
    {
        return 1;
    }
    if ((ch1=='*'||ch1=='/')&&(ch2=='+'||ch2=='-'))
    {
        return 1;
    }
    if ((ch1=='+'||ch1=='-')&&(ch2=='*'||ch2=='/'))
    {
        return 0;
    }
    
    return 1; 
}

void countValue(stackint* stack,int before,int after,char ch)
{
    int result;
    switch(ch){
        case '+':result=before+after;break;
        case '-':result=before-after;break;
        case '*':result=before*after;break;
        case '/':result=before/after;break;
    }
    Intpush(stack,result);
}

//表达式的最终计算
int finallyCount(stackint* stack,stacksign* signs)
{
    int before;
    int after;
    int ch;
    while (signs->StackPoint!=-1)
    {
        after=Intpop(stack);
        before=Intpop(stack);
        ch=charpop(signs);
        if (ch=='-')
        {
            after=-after;
            ch='+';
        }
        
        countValue(stack,before,after,ch);
    }
    return stack->Stack[0];    
}

int finalResult(char* chs)
{
    int i=0;
    int Intcounts[5];
    int countindex=0;
    char ch;
    int judgeI=1;
		int cou;
    stackint Numbers;
	  stacksign Signs;
    Numbers.StackPoint=-1;
    Signs.StackPoint=-1;

    while(chs[i]!='\0')
    {
        ch=chs[i++];
        if (juadgeNum(ch))
        {
            Intcounts[countindex++]=(ch-48);
            Intcounts[countindex]=-1;
            // Intpush(&Numbers,ch-48);
        }
        else
        {
            if (judgeI==1)
            {
                charToNum(&Numbers,Intcounts);
                countindex=0;
            }


            if(judgeSigned(ch,Signs.Stack[Signs.StackPoint])||Signs.StackPoint==-1)
            {
                charpush(&Signs,ch);
                judgeI=1;
            }
            else{
                //分别出栈计算表达式
                countValue(&Numbers,Intpop(&Numbers),Intpop(&Numbers),charpop(&Signs));
                i--;
                Signs.Stack[Signs.StackPoint+1]='#';
                judgeI=0;
            }

        }
    }
    charToNum(&Numbers,Intcounts);
    countindex=0;

     cou=finallyCount(&Numbers,&Signs);
    return cou;

}

void main()
{
	char ch;
	char chs[20];
	int result;
	unsigned char countx=0;
	unsigned char y=1;
	unsigned char countIndexKey=1;
	int xx;
	LCD_Init();	
	while(1)
	{
		ch=MatrixKey();
		if(ch!='x' && ch!='a' && ch!='N')
		{
			chs[countIndexKey-1]=ch;
			LCD_ShowChar(1,countIndexKey++,ch);
		}
		if(ch=='a')
		{
			LCD_Init();
			countIndexKey=1;
		}
		if(ch=='N')
		{
			chs[countIndexKey-1]='\0';
			result=finalResult(chs);

			xx=result;
			while(y!=0)
			{
				y=xx/10;
        xx/=10;
        countx++;
			}
			LCD_ShowChar(2,1,'=');
			LCD_ShowNum(2,2,result,countx);
		}
	}
}